import os.path

class Bunch:
    def __init__(self, **kwds):
        self.__dict__.update(kwds)

file_in = open('tilesunprocessed.txt', 'r')
file_out = open('tilesprocessed.java', 'w')

data_in = file_in.readlines()

# ignore comments '#'

def parseEdges(string, tile, buildObjects=False) :
    r_count = string.count('R')
    tokens = string.split(',')
    print string
    assert(len(tokens)==4)
       
    objects = []
    
    if buildObjects:
        previousLetter = '';
        previousObject = None
        currentObject = None
        currentRoad = None
        
        # for each element on an edge
        for i in range(len(tokens)):
            edgestr = tokens[i]
            for j in range(len(edgestr)):
                letter = edgestr[j]
                 
                if (letter!=previousLetter):
                    addit = True
                    
                    if letter=='F':
                        currentObject = Bunch(type='FARM',edges=[[],[],[],[]])
                    elif letter=='C':
                        currentObject = Bunch(type='CITY',edges=[[],[],[],[]])
                    elif letter=='R':
                        if currentRoad:
                            currentObject = currentRoad
                            addit = False
                        else:                        
                            currentObject = Bunch(type='ROAD',edges=[[],[],[],[]])
                            if r_count==2:
                                currentRoad = currentObject
                        
                    currentObject.edges[i].append(j)
                    
                    # we add the object
                    if addit:
                        objects.append(currentObject)
                        
                    previousObject = currentObject                
                                        
                else: #letter==previousLetter
                    previousObject.edges[i].append(j)
                
                previousLetter = letter
    
        # handle the wraparound condition
        if (len(objects)>1 and objects[-1].type==objects[0].type):
            #merge objects[0] and previousObject
            ot = objects[0]
            pt = objects[-1]
            for i in range(len(ot.edges)):
                ot.edges[i].extend(pt.edges[i])
                ot.edges[i].sort()
            del objects[-1]
    
    edges = []
    for t in tokens:
        l = []
        for ch in t:
            l.append({'R':'ROAD','C':'CITY','F':'FARM'}[ch])        
        edges.append(l)
    
    tile['edges'] = edges
    if buildObjects:
        tile['features'] = objects

def parseObjects(string, tile):
    specs = string.split(',')
    objects = []
    for spec in specs:
        # a spec is a character followed by a list of char/number pairs
        obj = Bunch(type={'R':'ROAD','C':'CITY','F':'FARM'}[spec[0]],edges=[[],[],[],[]])
        for i in range((len(spec)-1)/2):
            dir = spec[2*i+1]
            index = int(spec[2*i+2])
            obj.edges[{'t':0,'r':1,'b':2,'l':3}[dir]].append(index-1)
        for e in obj.edges:
            e.sort()
        objects.append(obj)
    tile['features'] = objects
        

def parseMeeples(string, tile) :
    print string
    # city_corner_road
    # C,FRF,FRF,C
    # Ct1l1,Fr1b3,Fr3b1,Rr2b2
    # K1414_11, F4214_21, T2929_22, F3838_23
    # F1532_11, T3020_12, F3909_13
    tokens = string.split(',')

    locations = []

    for loc in tokens :
        print loc
        type = loc[0]
        x = int(loc[1] + loc[2])
        y = int(loc[3] + loc[4])

        theFeature = None

        # always only one cloister so no need to link to it for monks
        if type == 'M' :
            pass   # cloisters feature not added in tilefactory as yet
            # If 'M' then can assume a cloister exits.
            # Only one cloister meeple location, and it is the center of the tile
            theFeature = Bunch(type='CLOISTER',edges=[[],[],[],[]])
            tile['features'].append(theFeature)
            location = Bunch(type='MONK',tile=tile,feature=theFeature, featureIndex=len(tile['features'])-1, pos=(x,y))
            locations.append(location)
        else :
            edge = int(loc[6]) - 1      # minus one since indexed from 1 in unprocessed file
            edge_index = int(loc[7]) - 1
        

            # for all features for this tile, find the one containing the edge for this location. i.e, find out which feature this location is for
            for i in range(0,len(tile['features'])) : #f in tile['features'] :
                f = tile['features'][i]
                if f.edges[edge].count(edge_index) :
                    theFeature = f        
                    break


            location = Bunch(type={'K':'KNIGHT','F':'FARMER','T':'THIEF','M':'MONK'}[type],tile=tile,feature=theFeature, featureIndex=i, pos=(x,y))
            locations.append(location)

    # add all these locations to this tile
    tile['meeplelocations'] = locations


##### ENTRY POINT #####


tiles = []

while data_in:    
    # if line doesn't start with a '#', then grab the tile name and number
    line = data_in.pop(0).rstrip()
    if not line[0] == '#' :
        (name,number) = line.split(",")
        tile = {}
        edges = data_in.pop(0).rstrip()
        objects = data_in.pop(0).rstrip()
        meeplelocations = data_in.pop(0).rstrip()
        tile['name'] = name
        tile['number'] = number
        
        if objects[0]=="-":
            parseEdges(edges, tile, True)
        else:
            parseEdges(edges,tile,False)
            parseObjects(objects,tile)
                
        if meeplelocations[0]=="-":
            tile['meeplelocations'] = []
        else:
            parseMeeples(meeplelocations, tile)

        tiles.append(tile)

for t in tiles:
    print 'Name: ', t['name']
    print 'Number: ', t['number']
    print 'Edges: ', t['edges']
    print 'Features: ' 
    for f in t['features']:
        print f.type, f.edges    
    print 'Meeple Locations: ' 
    for m in t['meeplelocations']:
        print m.type, m.feature.type, m.featureIndex, m.pos
        
# output data into java code 
file_out.write("\t//The names of the tiles\n\tpublic static final String[] tileNames = \n\t{\n")
for t in tiles:
    file_out.write("\t\t\"")
    file_out.write(t['name'])
    file_out.write("\",\n")
file_out.write("\t};\n")    
    
file_out.write("\t//The number of the tiles. i.e, tile distribution\n")
file_out.write("\tpublic static final HashMap<String, Integer> tileDistribution = new HashMap<String, Integer>() \n")
file_out.write("\t{\n")
file_out.write("\t\t{\n")
for t in tiles:
    file_out.write("\t\t\tput(\"")
    file_out.write(t['name'])
    file_out.write("\", new Integer(")
    file_out.write(t['number'])
    file_out.write("));\n")
file_out.write("\t\t}\n")    
file_out.write("\t};\n")    

file_out.write("""
    static public void fillTileData(Tile t)
    {    
        String name = t.tile;
    """);

started = False
for t in tiles:
    if started:
        file_out.write("\t\telse ")
        file_out.write("if (name==\"" + t['name'] + "\")\n\t\t{\n")    
    else: 
        started = True
        file_out.write("\tif (name==\"" + t['name'] + "\")\n\t\t{\n")    
    edges = t['edges']
    for i in range(len(edges)):
        tags = edges[i]
        file_out.write("\t\t\tt.edges[%d] = new int[%d];\n"%(i,len(tags)));
        for j in range(len(tags)):
            file_out.write("\t\t\tt.edges[%d][%d] = Tile.%s;\n"%(i,j,tags[j]))
    features = t['features']
    featureindex = 0
    for f in features:
        file_out.write("\t\t\tTile.Feature f%d = new Tile.Feature(t,Tile.%s);\n"%(featureindex,f.type))
        for i in range(len(f.edges)):
            edgespec = f.edges[i]
            if (len(edgespec)>0):
                file_out.write("\t\t\tf%d.connectedTo[%d] = new int[%d];\n"%(featureindex,i,len(edgespec)))
                for j in range(len(edgespec)):
                    file_out.write("\t\t\tf%d.connectedTo[%d][%d] = %d;\n"%(featureindex,i,j,edgespec[j]))
        file_out.write("\t\t\tt.features.add(f%d);\n"%(featureindex));
        featureindex += 1
            
    meeplelocations = t['meeplelocations']
    meeplelocationindex = 0
    for m in meeplelocations:
        file_out.write("\t\t\tTile.MeepleLocation m%d = new Tile.MeepleLocation(t,Meeple.%s,f%d,%d,%d);\n"%(meeplelocationindex,m.type,m.featureIndex, m.pos[0], m.pos[1]))
        file_out.write("\t\t\tt.meeple_locations.add(m%d);\n"%(meeplelocationindex));
        meeplelocationindex += 1
    
    file_out.write("\t\t}\n")

file_out.write("\n\t}");







